package com.fjnu.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Aspect
@Component
@Slf4j
public class LoggingAspect {
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    // 切入点：DAO层所有方法
    @Pointcut("execution(* com.fjnu.dao..*.*(..))")
    public void daoLayerAllMethods() {}

    // DAO层方法执行日志记录
    @Around("daoLayerAllMethods()")
    public Object logDaoMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable {
        String methodName = joinPoint.getSignature().getName();
        String className = joinPoint.getTarget().getClass().getSimpleName();
        long startTime = System.currentTimeMillis();

        try {
            log.info("[INFO] [{}] {}.{} method started.",
                    LocalDateTime.now().format(formatter), className, methodName);

            Object result = joinPoint.proceed();

            long endTime = System.currentTimeMillis();
            double spentTime = (endTime - startTime) / 1000.0;

            log.info("[INFO] [{}] {}.{} method was executed and spent {} second.",
                    LocalDateTime.now().format(formatter), className, methodName, spentTime);

            return result;

        } catch (Throwable throwable) {
            long endTime = System.currentTimeMillis();
            double spentTime = (endTime - startTime) / 1000.0;

            log.error("[ERROR] [{}] {}.{} method execution failed and spent {} second. Error: {}",
                    LocalDateTime.now().format(formatter), className, methodName, spentTime,
                    throwable.getMessage());
            throw throwable;
        }
    }
}
